package fun.hijklmn.magic.admin.server.handler;

import com.google.common.collect.Maps;
import fun.hijklmn.magic.admin.server.properties.JwtProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Map;

/**
 * @Description
 * @Author fs
 * @Date 2021/6/25 17:09
 * @Version 0.0.1-SNAPSHOT
 **/
@Component
public class JwtHandler implements InitializingBean {

    @Autowired
    private JwtProperties jwtProperties;

    public String getUsername(String token) {
        return getToken(token).getSubject();
    }

    public String getRole(String token) {
        return (String) getToken(token).get(jwtProperties.getRoleClaims());
    }

    public String getUserId(String token) {
        return getToken(token).getId();
    }

    public boolean isExpire(String token) {
        return LocalDateTime.ofInstant(getToken(token).getExpiration().toInstant(), ZoneId.systemDefault()).isBefore(LocalDateTime.now());
    }

    public Claims getToken(String token) {
        return Jwts.parser().setSigningKey(jwtProperties.getSecret()).parseClaimsJws(token).getBody();
    }

    public String createToken(String id, String username, String role, boolean isRemember) {
        long expire1 = isRemember ? jwtProperties.getRememberMeExpire() : jwtProperties.getExpire();
        Map<String, Object> claimsMap = Maps.newHashMap();
        claimsMap.put(jwtProperties.getRoleClaims(), role);
        claimsMap.put("id", id);
        LocalDateTime curLocalDateTime = LocalDateTime.now();
        return Jwts.builder().signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()).setClaims(claimsMap).setIssuer(jwtProperties.getIss()).setSubject(username).setIssuedAt(Date.from(curLocalDateTime.atZone(ZoneId.systemDefault()).toInstant())).setExpiration(Date.from(curLocalDateTime.plusSeconds(expire1).atZone(ZoneId.systemDefault()).toInstant())).compact();
    }

    @Override
    public void afterPropertiesSet() throws Exception {

    }
}
